package org.saxonextensions.eml.dispatcher;

import org.saxonextensions.eml.emitter.MailSessionFactory;
import org.saxonextensions.eml.emitter.MimeMessageWrapper;

import javax.mail.Session;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Email Dispatcher. Primary designed to dispatch serialized messages.
 *
 * @author Ivan Latysh <ivan@yourmail.com>
 * @version 0.1
 * @since 4-Mar-2009 11:18:18 AM
 */
public abstract class AbstractFileEMLDispatcher extends AbstractThreadedEMLDispatcher {
  // Error prefix EMLFD00002

  /** Logger */
  protected Logger logger = Logger.getLogger(this.getClass().getName());

  /**
   * Dispatch all found eml files from given directory
   *
   * @throws Exception when unable to dispatch messages
   */
  public void dispatchAll(File directory) throws Exception {
    // check firectory
    if (!directory.isDirectory()) {
      logger.log(Level.SEVERE, "[EMLFD00001] Directory {"+directory.getAbsolutePath()+"} is not a directory.");
      throw new Exception("[EMLFD00001] Directory {"+directory.getAbsolutePath()+"} is not a directory.");
    }

    // list files
    File[] files = directory.listFiles(emlFilter);
    // check what have we found
    if (files.length==0) {
      // nothing to do
      return;
    } else {
      // log number of discovered files and proceed.
      logger.info("Discovered "+files.length+" file(s).");
    }

    // processed messages counter
    int counter = 0;
    try {
      // process all files
      for (File file: files) {
        // skip nulls and not files
        if (null==file || !file.isFile()) continue;
        // skip files that I can't read
        if (!file.canRead()) continue;
        // message input stream
        InputStream msgIn = null;
        try {
          msgIn = new FileInputStream(file);
          // deserialize message
          MimeMessageWrapper mwrapper = new MimeMessageWrapper(getSession(), msgIn);
          // send message
          dispatch(mwrapper);
          // increase counter
          counter ++;
        } catch (Exception ex) {
          logger.log(Level.SEVERE, "Unable to process a message from file {"+file.getAbsolutePath()+"}", ex);
        } finally {
          // close the stream
          if (null!=msgIn) try {
            msgIn.close();
          } catch (IOException e) {
            logger.log(Level.SEVERE, "Unable to close input stream for file {"+file.getAbsolutePath()+"}");
          }
          // destroy the file
          if (!file.delete()) logger.log(Level.SEVERE, "Unable to delete the file {"+file.getAbsolutePath()+"}");
        }
      }
    } finally {
      // log progress
      logger.log(Level.INFO, "Processed "+counter+" files.");
    }
  }

  /** {@inheritDoc} */
  public Session getSession() throws Exception {
    return MailSessionFactory.getSession();
  }

  /**
   * `eml` filename filter.
   */
  protected FilenameFilter emlFilter = new FilenameFilter() {
    public boolean accept(File dir, String name) {
      return name.endsWith(".eml");
    }
  };

}